﻿using System;
using System.Collections.Generic;
using System.Drawing;
using System.Text;

namespace AGHFiraPlayer.Strategies.StrategyAdvisiors
{
    class BasicStrategyAdvisor : IStrategyAdvisor
    {
        private AGHDriver driver;
        private int involvedPlayers, maxApplicabilityLevel, applicabilityLevel, i, j, l;
        private List<IStrategy> choosenStrategies;
        private List<IStrategy> strategies;
        private IStrategy choosenStrategy;
        private Type currentType, newType;

        public BasicStrategyAdvisor(AGHDriver driver)
        {
            this.driver = driver;
        }

        public List<IStrategy> advice()
        {
            involvedPlayers = 0;
            choosenStrategies = new List<IStrategy>();

            while (involvedPlayers != driver.Robots.Count + 1) {
                strategies = StrategiesManager.getAllowedStrategies();
                if (strategies.Count == 0)
                    break;
                maxApplicabilityLevel = strategies[0].applicabilityLevel(ref choosenStrategies);
                choosenStrategy = strategies[0];

                for (int i = 1; i < strategies.Count; i++)
                {
                    applicabilityLevel = strategies[i].applicabilityLevel(ref choosenStrategies);

                    if (applicabilityLevel > maxApplicabilityLevel)
                    {
                        maxApplicabilityLevel = applicabilityLevel;
                        choosenStrategy = strategies[i];
                    }
                }

                strategies.Remove(choosenStrategy);
                StrategiesManager.returnToPool(strategies);
                foreach (IStrategy strategy in strategies) {
                    strategy.clearCachedValues();
                }

                choosenStrategies.Add(choosenStrategy);
                choosenStrategy.setCurrentApplicability(maxApplicabilityLevel);
                choosenStrategy.flagChoosenRobots();
                involvedPlayers += choosenStrategy.involvesPlayers();
            }

            refreshDataTable(choosenStrategies);
            return choosenStrategies;
        }

        public void gameStateOff()
        {
            driver.gameStateOff();
        }

        public void startupPositions()
        {
            driver.startupPositions();
        }

        private void refreshDataTable(List<IStrategy> choosenStrategies) 
        {
            for (i = 0; i < choosenStrategies.Count; i++)
            {
                List<RobotController> involvedRobots = choosenStrategies[i].getInvolvedRobots();
                for (j = 0; j < involvedRobots.Count; j++)
                {
                    for (l = 0; l < AGHFiraPlayer.PotencialDriverForm.dataTable.Rows.Count; l++)
                    {
                        if (AGHFiraPlayer.PotencialDriverForm.dataTable.Rows[l][0] == involvedRobots[j].robotState)
                        {
                            currentType = AGHFiraPlayer.PotencialDriverForm.dataTable.Rows[l][1].GetType();
                            newType = choosenStrategies[i].GetType();
                            if (currentType != newType)
                                AGHFiraPlayer.PotencialDriverForm.dataTable.Rows[l][1] = choosenStrategies[i];
                            if ((int)AGHFiraPlayer.PotencialDriverForm.dataTable.Rows[l][2] != choosenStrategies[i].getCurrentApplicability())
                                AGHFiraPlayer.PotencialDriverForm.dataTable.Rows[l][2] = choosenStrategies[i].getCurrentApplicability();
                            break;
                        }
                    }
                }
            }
        }
    }
}
